package utils

import "math/cmplx"

type Array1d struct {
	D []complex128
}

func NewArray1d(len int) Array1 {
	return &Array1d{
		D: make([]complex128, len),
	}
}

type Array2d struct {
	D [][]complex128
}

func NewArray2d(len0, len1 int) Array2 {
	D := make([][]complex128, len0)
	for i := 0; i < len0; i++ {
		D[i] = make([]complex128, len1)
	}
	return &Array2d{
		D: D,
	}
}

type Array3d struct {
	D [][][]complex128
}

func Array3dByD(d [][][]complex128) Array3 {
	return &Array3d{d}
}

func NewArray3d(len0, len1, len2 int) Array3 {
	D := make([][][]complex128, len0)
	for i := 0; i < len0; i++ {
		D[i] = make([][]complex128, len1)
		for j := 0; j < len1; j++ {
			D[i][j] = make([]complex128, len2)
		}
	}
	return &Array3d{
		D: D,
	}
}

type Array1 *Array1d
type Array2 *Array2d
type Array3 *Array3d

func AbsMax1D(x []float64) (idx int, amp float64) {
	amp = x[0]
	idx = 0
	for i, v := range x {
		if v > amp {
			idx = i
			amp = v
		}
	}
	return
}
func AbsMax2D(sx [][]float64) (idx [2]int, amp float64) {
	x := make([]float64, len(sx))
	idx0 := make([]int, len(sx))
	for i, v := range sx {
		idx0[i], x[i] = AbsMax1D(v)
	}
	idx[0], amp = AbsMax1D(x)
	idx[1] = idx0[idx[0]]
	return
}
func AbsMax3D(sx [][][]float64) (idx [3]int, amp float64) {
	x := make([]float64, len(sx))
	idx0 := make([][2]int, len(sx))
	for i, v := range sx {
		idx0[i], x[i] = AbsMax2D(v)
	}
	idx[0], amp = AbsMax1D(x)
	idx[1] = idx0[idx[0]][0]
	idx[2] = idx0[idx[0]][1]
	return
}
func CAbsMax1D(cx []complex128) (idx int, amp float64) {
	x := make([]float64, len(cx))
	for i, v := range cx {
		x[i] = cmplx.Abs(v)
	}
	return AbsMax1D(x)
}

func CAbsMax2D(cx [][]complex128) (idx [2]int, amp float64) {
	x := make([]float64, len(cx))
	idx0 := make([]int, len(cx))
	for i, v := range cx {
		idx0[i], x[i] = CAbsMax1D(v)
	}
	idx[0], amp = AbsMax1D(x)
	idx[1] = idx0[idx[0]]
	return
}

func CAbsMax3D(cx [][][]complex128) (idx [3]int, amp float64) {
	x := make([]float64, len(cx))
	idx0 := make([][2]int, len(cx))
	for i, v := range cx {
		idx0[i], x[i] = CAbsMax2D(v)
	}
	idx[0], amp = AbsMax1D(x)
	idx[1] = idx0[idx[0]][0]
	idx[2] = idx0[idx[0]][1]
	return
}
